package com.example.demo.pdfbox.util;

import com.example.demo.pdfbox.common.FontClass;
import com.example.demo.pdfbox.common.PdfBorder;
import com.example.demo.pdfbox.common.Position;
import com.example.demo.pdfbox.common.enums.*;
import com.example.demo.pdfbox.tabel.PdfParagraph;
import com.example.demo.pdfbox.tabel.concrete.PdfGraph;
import com.example.demo.pdfbox.tabel.concrete.PdfLine;
import com.example.demo.pdfbox.tabel.concrete.PdfText;
import com.example.demo.pdfbox.tabel.form.PdfColumn;
import com.example.demo.pdfbox.tabel.form.PdfRow;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.util.Matrix;
import org.springframework.beans.BeanUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class PdfUtil {

    public static float LINE_BASE = 1.45F;

    public static void drawBackGround(PDPageContentStream contentStream, Position position, PdfColumn column, PdfBorder pdfBorder, PdfRow pdfRow, float height, float width) throws IOException {
        // 背景高度，取行高
        contentStream.setLineWidth(pdfRow.getHeight());
        if (column.getBackgroundColor() != null) {
            contentStream.setStrokingColor(column.getBackgroundColor());
            contentStream.setNonStrokingColor(column.getBackgroundColor());
        } else if (pdfBorder != null && pdfBorder.getBackgroundColor() != null) {
            contentStream.setStrokingColor(pdfBorder.getBackgroundColor());
            contentStream.setNonStrokingColor(pdfBorder.getBackgroundColor());

        }
        BackgroundStyle backgroundStyle = null;
        if (column.getBackgroundStyle() != null) {
            backgroundStyle = column.getBackgroundStyle();
        } else if (pdfBorder != null && pdfBorder.getBackgroundStyle() != null) {
            backgroundStyle = pdfBorder.getBackgroundStyle();
        }

        if (backgroundStyle == BackgroundStyle.FULL) {
            // 实线无间隔
            contentStream.setLineDashPattern(BorderStyle.SOLID.getPattern(), BorderStyle.SOLID.getPhase());
            // 设置Y轴起始位置，背景占位为当前位置向上高度
            contentStream.moveTo(position.startX, position.startY - height / 2);
            contentStream.lineTo(position.startX + width, position.startY - height / 2);
            contentStream.stroke();

            // 背景
            if (column.getBackgroundColor() != null) {
                contentStream.setStrokingColor(column.getBackgroundColor());
            } else if (pdfBorder != null && pdfBorder.getBackgroundColor() != null) {
                contentStream.setStrokingColor(pdfBorder.getBorderColor());
            }
        } else if (backgroundStyle == BackgroundStyle.SHAPE) {
            float radio = 0;
            if (column.getRadio() != null) {
                radio = column.getRadio();
            } else if (pdfBorder != null && pdfBorder.getRadio() != null) {
                radio = pdfBorder.getRadio();
            }


            // 背景
            contentStream.moveTo(position.startX + radio, position.startY - height);
            contentStream.curveTo(position.startX + radio, position.startY - height, position.startX, position.startY - height, position.startX, position.startY - height + radio);
            contentStream.lineTo(position.startX, position.startY - radio);
            contentStream.curveTo(position.startX, position.startY - radio, position.startX, position.startY, position.startX + radio, position.startY);
            contentStream.lineTo(position.startX + width - radio, position.startY);
            contentStream.curveTo(position.startX + width - radio, position.startY, position.startX + width, position.startY, position.startX + width, position.startY - radio);
            contentStream.lineTo(position.startX + width, position.startY - height + radio);
            contentStream.curveTo(position.startX + width, position.startY - height + radio, position.startX + width, position.startY - height, position.startX + width - radio, position.startY - height);
            contentStream.lineTo(position.startX + radio, position.startY - height);

            contentStream.closePath(); // Close the path
            contentStream.fill();
        }

    }

    public static void drawBorder(PDPageContentStream contentStream, Position position, PdfColumn column, PdfBorder pdfBorder, Rectangle rectangle, float height, float width) throws IOException {
        float lineWidth = 0;
        Float radio = null;
        // 设置宽度
        if (column.getBorderSize() != null) {
            lineWidth = column.getBorderSize();
        } else if (pdfBorder != null && pdfBorder.getBorderSize() != null) {
            lineWidth = pdfBorder.getBorderSize();
        }
        contentStream.setLineWidth(lineWidth);

        // 设置颜色
        if (column.getBorderColor() != null) {
            contentStream.setStrokingColor(column.getBorderColor());
        } else if (pdfBorder != null && pdfBorder.getBorderColor() != null) {
            contentStream.setStrokingColor(pdfBorder.getBorderColor());
        }
        // 设置线样式
        if (column.getBorderStyle() != null) {
            contentStream.setLineDashPattern(column.getBorderStyle().getPattern(), column.getBorderStyle().getPhase());
        } else if (pdfBorder != null && pdfBorder.getBorderStyle() != null) {
            contentStream.setLineDashPattern(pdfBorder.getBorderStyle().getPattern(), pdfBorder.getBorderStyle().getPhase());
        }
        byte border = rectangle.getBorder();
        // 圆角
        if (column.getRadio() != null) {
            radio = column.getRadio();
        } else if (pdfBorder != null && pdfBorder.getRadio() != null) {
            radio = pdfBorder.getRadio();
        }
        // 边框
        // 左边框
        if ((border >> 3 & 0x01) == 1) {
            // 下
            if ((border & 0x01) == 1 && radio != null) {
                contentStream.moveTo(position.startX + radio, position.startY - height);
                contentStream.curveTo(position.startX + radio, position.startY - height, position.startX, position.startY - height, position.startX, position.startY - height + radio);
            } else {
                contentStream.moveTo(position.startX, position.startY - height - lineWidth / 2);
            }
            // 上
            if ((border >> 2 & 0x01) == 1 && radio != null) {
                contentStream.lineTo(position.startX, position.startY - radio);
                contentStream.curveTo(position.startX, position.startY - radio, position.startX, position.startY, position.startX + radio, position.startY);
            } else {
                contentStream.lineTo(position.startX, position.startY + lineWidth / 2);
            }
            contentStream.stroke();
        }

        // 上边框
        if ((border >> 2 & 0x01) == 1) {
            // 左
            if ((border >> 3 & 0x01) == 1 && radio != null) {
                contentStream.moveTo(position.startX + radio, position.startY);
            } else {
                contentStream.moveTo(position.startX, position.startY);
            }
            // 右
            if ((border >> 1 & 0x01) == 1 && radio != null) {
                contentStream.lineTo(position.startX + width - radio, position.startY);
            } else {
                contentStream.lineTo(position.startX + width, position.startY);
            }
            contentStream.stroke();
        }

        // 右边框
        if ((border >> 1 & 0x01) == 1) {
            // 上
            if ((border >> 2 & 0x01) == 1 && radio != null) {
                contentStream.moveTo(position.startX + width - radio, position.startY);
                contentStream.curveTo(position.startX + width - radio, position.startY, position.startX + width, position.startY, position.startX + width, position.startY - radio);
            } else {
                contentStream.moveTo(position.startX + width, position.startY + lineWidth / 2);
            }
            // 下
            if ((border & 0x01) == 1 && radio != null) {
                contentStream.lineTo(position.startX + width, position.startY - height + radio);
                contentStream.curveTo(position.startX + width, position.startY - height + radio, position.startX + width, position.startY - height, position.startX + width - radio, position.startY - height);
            } else {
                contentStream.lineTo(position.startX + width, position.startY - height - lineWidth / 2);
            }
            contentStream.stroke();
        }

        // 下边框
        if ((border & 0x01) == 1) {
            // 右
            if ((border >> 1 & 0x01) == 1 && radio != null) {
                contentStream.moveTo(position.startX + width - radio, position.startY - height);
            } else {
                contentStream.moveTo(position.startX + width, position.startY - height);
            }
            // 左
            if ((border >> 3 & 0x01) == 1 && radio != null) {
                contentStream.lineTo(position.startX + radio, position.startY - height);
            } else {
                contentStream.lineTo(position.startX, position.startY - height);
            }
            contentStream.stroke();
        }
    }

    public static void generateParagraph(PDPageContentStream contentStream, FontClass fontClass, PdfColumn column, Position pos, float width, float height) throws IOException {
        PdfParagraph paragraph = (PdfParagraph) column.getElement();
        pos.startX += paragraph.getX();
        pos.startY += paragraph.getY() ;
        float startX = pos.startX;


        HorizontalAlignment horizontalAlignment = paragraph.getHorizontalAlignment();
        VerticalAlignment verticalAlignment = paragraph.getVerticalAlignment();
        // 多行 段落行数
        int rowNum = paragraph.getRowNum();
        List<List<PdfText>> rowItems = paragraph.getRowItems();
        for (int r = 0; r < rowNum; r++) {
            float textWidth = 0;
            float textHeight = 0;
            float nextWidth = 0;
            if (r + 1 < rowNum) {
                List<PdfText> textList = rowItems.get(r + 1);
                for (PdfText pdfText : textList) {
                    nextWidth = Math.max(PdfUtil.getStringHeight(fontClass, pdfText.isBlock(), pdfText.getFontSize()), textHeight);
                }
            }
            List<PdfText> textList = rowItems.get(r);
            for (PdfText pdfText : textList) {
                textWidth += PdfUtil.getStringWidth(fontClass, pdfText.getName(), pdfText.isBlock(), pdfText.getFontSize());
                textHeight = Math.max(PdfUtil.getStringHeight(fontClass, pdfText.isBlock(), pdfText.getFontSize()), textHeight);
            }
            // 位置
            if (horizontalAlignment == HorizontalAlignment.CENTER) {
                // 居中
                pos.startX += (width - textWidth) / 2 + column.getPaddingLeft();
            } else if (horizontalAlignment == HorizontalAlignment.LEFT) {
                // 居左
                pos.startX = pos.startX + column.getPaddingLeft();
            } else if (horizontalAlignment == HorizontalAlignment.RIGHT) {
                // 居右
                pos.startX = pos.startX + width - textWidth + column.getPaddingLeft();
            }

            if (r == 0) {
                float h = 0;
                float h0 = 0;
                for (int n = 0; n < rowNum; n++) {
                    List<PdfText> rowItem = rowItems.get(n);
                    float t = 0;
                    for (PdfText pdfText : rowItem) {
                        t = Math.max(PdfUtil.getStringHeight(fontClass, pdfText.isBlock(), pdfText.getFontSize()), t);
                    }
                    if (n == 0) {
                        h0 = t;
                    }
                    h = h + t * LINE_BASE + paragraph.getSpaced();
                }
                if (verticalAlignment == VerticalAlignment.BOTTOM) {
                    // 底部
                    pos.startY = pos.startY - height + h + column.getPaddingBottom() - h0 * (LINE_BASE + 1) / 2;
                    // pos.startY = pos.startY - height + (h + rowNum * paragraph.getSpaced()) + textHeight - column.getPaddingTop();
                } else if (verticalAlignment == VerticalAlignment.CENTER) {
                    // 居中
                    if (h + column.getPaddingTop() + column.getPaddingBottom() == height) {
                        pos.startY = pos.startY - column.getPaddingTop() - h0 * (LINE_BASE + 1) / 2;
                    } else {
                        pos.startY = pos.startY - (height - column.getPaddingTop() - column.getPaddingBottom() - h) / 2 - column.getPaddingTop() - h0 * (LINE_BASE + 1) / 2;
                        // pos.startY = pos.startY - height / 2 + (h) / 2 - h0  - column.getPaddingTop();
                    }
                }
            }

            for (PdfText pdfText : textList) {
                float stringWidth = PdfUtil.getStringWidth(fontClass, pdfText.getName(), pdfText.isBlock(), pdfText.getFontSize());
                float stringHeight = PdfUtil.getStringHeight(fontClass, pdfText.isBlock(), pdfText.getFontSize());
                // 文字
                generateText(contentStream, fontClass, pos, pdfText, stringHeight, stringWidth);
                pos.startX += stringWidth;
            }
            pos.startX = startX;
            pos.startY = pos.startY - nextWidth * LINE_BASE - paragraph.getSpaced();
        }
    }

    public static void computeParagraph(FontClass fontClass, float width, float columnHeight, PdfParagraph paragraph, float rowHeight) {
        boolean flag = false;
        int rowNum = 0;
        List<List<PdfText>> rowItems = new ArrayList<>();
        rowItems.add(new ArrayList<>());
        List<PdfText> textList = paragraph.getTextList();

        // 边距
        float stWidth = 0;
        String s;
        boolean lastEndsWithBlank = false;
        float fontHeight = 0;
        StringBuilder builder = new StringBuilder();
        for (PdfText pdfText : textList) {
            if (flag) {
                break;
            }
            String[] split = pdfText.getName().split(" ");
            float curFontHeight = PdfUtil.getStringHeight(fontClass, pdfText.isBlock(), pdfText.getFontSize());
            boolean nextLine = pdfText.isNextLine();
            for (int k = 0; k < split.length; k++) {
                if (k != 0) {
                    nextLine = false;
                }
                if (flag) {
                    break;
                }
                // 结尾空格或以空格划分
                if ((k == split.length - 1 && pdfText.getName().endsWith(" ")) || k < split.length - 1) {
                    s = split[k] + " ";
                } else {
                    s = split[k];
                }
                boolean thisEndsWithBlank = s.endsWith(" ");
                float curWidth = PdfUtil.getStringWidth(fontClass, s, pdfText.isBlock(), pdfText.getFontSize());
                // 当前行剩余宽度
                float remainWidth = width - stWidth;

                // 剩余宽度不足以显示全部文字或者换行
                if (remainWidth < curWidth || nextLine) {
                    // 剩余文字以空格结尾或设置换行，换新一行，否则继续当前行
                    if (lastEndsWithBlank || nextLine) {

                        // 保存上一行未存数据
                        if (builder.length() != 0) {
                            columnHeight += fontHeight * LINE_BASE + paragraph.getSpaced();
                            if (columnHeight > rowHeight) {
                                flag = true;
                                break;
                            }
                            PdfText text = new PdfText();
                            BeanUtils.copyProperties(pdfText, text);
                            text.setName(builder.toString());
                            // rowItems.add(new ArrayList<>());
                            rowItems.get(rowNum).add(text);
                            // rowItems.get(rowNum).setRowHeight(Math.max(curFontHeight, fontHeight));
                            builder.setLength(0);
                        } else {
                            columnHeight += fontHeight * LINE_BASE + paragraph.getSpaced();
                            if (columnHeight > rowHeight) {
                                flag = true;
                                break;
                            }
                        }
                        // 从新行计算所需行数
                        stWidth = 0;
                        rowNum++;
                        rowItems.add(new ArrayList<>());
                        // columnHeight += fontHeight * LINE_BASE + paragraph.getSpaced();
                        fontHeight = 0;
                        // rowItems.add(new ArrayList<>());

                    }
                    float lineHeight = Math.max(curFontHeight, fontHeight) * LINE_BASE + paragraph.getSpaced();
                    fontHeight=lineHeight;
                    for (char c : s.toCharArray()) {
                        float stringWidth = PdfUtil.getStringWidth(fontClass, c, pdfText.isBlock(), pdfText.getFontSize());
                        stWidth += stringWidth;
                        if (stWidth < width && columnHeight + lineHeight < rowHeight) {
                            builder.append(c);
                        } else {
                            // 当前列高度
                            columnHeight += lineHeight;
                            if (columnHeight > rowHeight) {
                                flag = true;
                                break;
                            }
                            PdfText text = new PdfText();
                            BeanUtils.copyProperties(pdfText, text);
                            text.setName(builder.toString());
                            // rowItems.add(new ArrayList<>());
                            rowItems.get(rowNum).add(text);
                            // rowItems.get(rowNum).setRowHeight(Math.max(curFontHeight, fontHeight));
                            builder.setLength(0);
                            builder.append(c);
                            stWidth = stringWidth;
                            // rowHeight += Math.max(curFontHeight, fontHeight) * LINE_BASE;
                            fontHeight = 0;
                            rowNum++;
                            rowItems.add(new ArrayList<>());
                        }
                    }
                } else {
                    // 剩余宽度足以显示全部文字
                    stWidth += curWidth;
                    builder.append(s);
                }
                lastEndsWithBlank = thisEndsWithBlank;
            }
            if (builder.length() != 0 && !flag) {
                PdfText text = new PdfText();
                BeanUtils.copyProperties(pdfText, text);
                text.setName(builder.toString());
                rowItems.get(rowNum).add(text);
                // rowItems.get(rowNum).setRowHeight(Math.max(curFontHeight, fontHeight));
                builder.setLength(0);
            }
            fontHeight = Math.max(fontHeight, curFontHeight);
        }

        if (!rowItems.get(rowNum).isEmpty()) {
            rowNum++;
        }

        paragraph.setRowItems(rowItems);
        paragraph.setRowNum(rowNum);
    }

    public static void computeParagraphForm(FontClass fontClass, PdfParagraph paragraph, PdfColumn column, PdfRow pdfRow, float width, float nextRowHeight) {
        float rowHeight = 0;
        List<List<PdfText>> rowItems = new ArrayList<>();
        rowItems.add(new ArrayList<>());
        int rowNum = 0;
        List<PdfText> textList = paragraph.getTextList();
        float stWidth = 0;

        String s;
        boolean lastEndsWithBlank = false;
        float fontHeight = 0;
        StringBuilder builder = new StringBuilder();

        if (!paragraph.isAutoLine()) {
            for (PdfText pdfText : textList) {
                // 计算长度超长位置
                String name = pdfText.getName();
                float stringWidth = PdfUtil.getStringWidth(fontClass, name, pdfText.isBlock(), pdfText.getFontSize());
                stWidth += stringWidth;
                // 截断
                if (stWidth > width && stWidth - stringWidth < width) {
                    builder = new StringBuilder();
                    stWidth -= stringWidth;
                    for (int n = 0; n < name.length(); n++) {
                        char c = name.charAt(n);
                        stWidth += PdfUtil.getStringWidth(fontClass, c, pdfText.isBlock(), pdfText.getFontSize());
                        if (stWidth < width) {
                            builder.append(c);
                        } else {
                            break;
                        }
                    }
                    PdfText text = new PdfText();
                    BeanUtils.copyProperties(pdfText, text);
                    text.setName(builder.toString());
                    rowItems.get(rowNum).add(text);
                    break;
                } else if (stWidth > width && stWidth - stringWidth > width) {
                    break;
                } else {
                    PdfText text = new PdfText();
                    BeanUtils.copyProperties(pdfText, text);
                    rowItems.get(rowNum).add(text);
                }
            }
        } else {
            for (int i = 0; i < textList.size(); i++) {
                PdfText pdfText = textList.get(i);
                String[] split = pdfText.getName().split(" ");
                float curFontHeight = PdfUtil.getStringHeight(fontClass, pdfText.isBlock(), pdfText.getFontSize());
                boolean nextLine = pdfText.isNextLine();
                for (int k = 0; k < split.length; k++) {
                    if (k != 0) {
                        nextLine = false;
                    }
                    // 结尾空格或以空格划分
                    if ((k == split.length - 1 && pdfText.getName().endsWith(" ")) || k < split.length - 1) {
                        s = split[k] + " ";
                    } else {
                        s = split[k];
                    }
                    boolean thisEndsWithBlank = s.endsWith(" ");
                    float curWidth = PdfUtil.getStringWidth(fontClass, s, pdfText.isBlock(), pdfText.getFontSize());

                    // 换行(按长度)
                    // 当前行剩余宽度
                    float remainWidth = width - stWidth;
                    // 剩余宽度不足以显示全部文字
                    if (remainWidth < curWidth) {
                        // 剩余文字以空格结尾或设置换行，换新一行，否则继续当前行
                        if (lastEndsWithBlank || nextLine) {
                            // 保存上一行未存数据
                            if (builder.length() != 0) {
                                PdfText text = new PdfText();
                                BeanUtils.copyProperties(pdfText, text);
                                text.setName(builder.toString());
                                rowItems.get(rowNum).add(text);
                                builder.setLength(0);
                            }
                            // 从新行计算所需行数
                            stWidth = 0;
                            rowHeight += Math.max(curFontHeight, fontHeight) * LINE_BASE;
                            fontHeight = 0;
                            rowNum++;
                            rowItems.add(new ArrayList<>());

                        }
                        for (char c : s.toCharArray()) {
                            float stringWidth = PdfUtil.getStringWidth(fontClass, c, pdfText.isBlock(), pdfText.getFontSize());
                            stWidth += stringWidth;
                            if (stWidth < width) {
                                builder.append(c);
                            } else {
                                PdfText text = new PdfText();
                                BeanUtils.copyProperties(pdfText, text);
                                text.setName(builder.toString());
                                rowItems.get(rowNum).add(text);
                                // rowItems.get(rowNum).setRowHeight(Math.max(curFontHeight, fontHeight));
                                builder.setLength(0);
                                builder.append(c);
                                stWidth = stringWidth;
                                rowHeight += Math.max(curFontHeight, fontHeight) * LINE_BASE;
                                fontHeight = 0;
                                rowNum++;
                                rowItems.add(new ArrayList<>());
                            }
                        }
                    } else {
                        // 设置换行，换新一行
                        if (nextLine) {
                            // 保存上一行未存数据
                            if (builder.length() != 0) {
                                PdfText text = new PdfText();
                                BeanUtils.copyProperties(pdfText, text);
                                text.setName(builder.toString());
                                rowItems.get(rowNum).add(text);
                                builder.setLength(0);
                            }
                            // 从新行计算所需行数
                            stWidth = 0;
                            rowHeight += Math.max(curFontHeight, fontHeight) * LINE_BASE;
                            fontHeight = 0;
                            rowNum++;
                            rowItems.add(new ArrayList<>());
                        }
                        // 剩余宽度足以显示全部文字
                        stWidth += curWidth;
                        builder.append(s);
                    }
                    lastEndsWithBlank = thisEndsWithBlank;
                }
                fontHeight = Math.max(fontHeight, curFontHeight);

                if (builder.length() != 0) {
                    if (i == textList.size() - 1) {
                        rowHeight += Math.max(curFontHeight, fontHeight) * LINE_BASE;
                    }
                    PdfText text = new PdfText();
                    BeanUtils.copyProperties(pdfText, text);
                    text.setName(builder.toString());
                    rowItems.get(rowNum).add(text);
                    builder.setLength(0);
                }
            }
        }

        // 行距
        rowNum++;
        rowHeight += rowNum * paragraph.getSpaced();

        if (paragraph.isAutoLine()) {
            if (rowHeight - nextRowHeight < pdfRow.getMinHeight()) {
                pdfRow.setHeight(pdfRow.getMinHeight() < pdfRow.getHeight() ? pdfRow.getHeight() : pdfRow.getMinHeight() + column.getPaddingTop() + column.getPaddingBottom());
            } else {
                pdfRow.setHeight(Math.max(rowHeight - nextRowHeight + column.getPaddingTop() + column.getPaddingBottom(), pdfRow.getHeight()));
            }
        }
        paragraph.setRowItems(rowItems);
        paragraph.setRowNum(rowNum);
    }

    public static void generateLine(PDPageContentStream contentStream, PdfLine pdfLine,Position position) throws IOException {

        // 控制点为控制为起点
        if (pdfLine.getX2() == null||pdfLine.getY2()==null) {
            pdfLine.setX2(pdfLine.getX1());
            pdfLine.setY2(pdfLine.getY1());
        }
        if (pdfLine.getX3()==null||pdfLine.getY3()==null){
            pdfLine.setX3(pdfLine.getX2());
            pdfLine.setY3(pdfLine.getY2());
        }
        contentStream.setLineWidth(pdfLine.getWidth());
        contentStream.setLineCapStyle(pdfLine.getLineCapStyle().getStyle());
        contentStream.setLineDashPattern(pdfLine.getBorderStyle().getPattern(), pdfLine.getBorderStyle().getPhase());
        contentStream.setStrokingColor(pdfLine.getColor());
        // 起点
        contentStream.moveTo(position.startX + pdfLine.getX1(), position.startY + pdfLine.getY1());
        // 贝赛尔曲线
        contentStream.curveTo(position.startX + pdfLine.getX2(), position.startY + pdfLine.getY2(), position.startX + pdfLine.getX3(), position.startY + pdfLine.getY3(), position.startX + pdfLine.getX4(), position.startY + pdfLine.getY4());
        contentStream.stroke();
    }

    public static void generateGraph(PdfGraph graph, PDPageContentStream contentStream, Position position) throws IOException {
        List<PdfLine> lines = graph.getLines();
        // 颜色填充
        if (graph.getFillColor() != null && lines.size() > 1) {
            contentStream.setNonStrokingColor(graph.getFillColor());
            for (int i = 0; i < lines.size(); i++) {
                PdfLine pdfLine = lines.get(i);
                // 控制点为控制为起点
                if (pdfLine.getX2() == null||pdfLine.getY2()==null) {
                    pdfLine.setX2(pdfLine.getX1());
                    pdfLine.setY2(pdfLine.getY1());
                }
                if (pdfLine.getX3()==null||pdfLine.getY3()==null){
                    pdfLine.setX3(pdfLine.getX2());
                    pdfLine.setY3(pdfLine.getY2());
                }
                if (i == 0) {
                    // 起点
                    contentStream.moveTo(position.startX + pdfLine.getX1(), position.startY + pdfLine.getY1());
                }
                // 贝赛尔曲线
                contentStream.curveTo(position.startX + pdfLine.getX2(), position.startY + pdfLine.getY2(), position.startX + pdfLine.getX3(), position.startY + pdfLine.getY3(), position.startX + pdfLine.getX4(), position.startY + pdfLine.getY4());

            }

            contentStream.closePath(); // Close the path
            contentStream.fill();

        }
        // 边框
        for (PdfLine line : lines) {
            generateLine(contentStream,line,position);
        }
    }
    public static void generateText(PDPageContentStream contentStream, FontClass fontClass, Position pos, PdfText pdfText, float stringHeight, float stringWidth) throws IOException {
        // 背景色
        if (pdfText.getBackGround() != null) {
            // 背景高度
            contentStream.setLineWidth(pdfText.getExtraTop() + pdfText.getExtraBottom() + stringHeight);
            contentStream.setStrokingColor(pdfText.getBackGround());
            // 实线无间隔
            contentStream.setLineDashPattern(BorderStyle.SOLID.getPattern(), BorderStyle.SOLID.getPhase());
            // 设置Y轴起始位置，背景占位为当前位置向上高度
            contentStream.moveTo(pos.startX - pdfText.getExtraLeft(), pos.startY + stringHeight / 2);
            contentStream.lineTo(pos.startX + stringWidth, pos.startY + stringHeight / 2);
            contentStream.stroke();
        }
        // 文字
        contentStream.beginText();
        contentStream.setFont(fontClass.getNormalFont(), pdfText.getFontSize());
        contentStream.setNonStrokingColor(pdfText.getTextColor());
        // 加粗，使用粗体文字
        if (pdfText.isBlock()) {
            contentStream.setFont(fontClass.getBoldFont(), pdfText.getFontSize());
        }
        // 斜体
        if (pdfText.isItalic()) {
            Matrix matrix = new Matrix(1, 0f, (float) Math.toRadians(10), 1, pos.startX, pos.startY);
            contentStream.setTextMatrix(matrix);
        } else {
            contentStream.newLineAtOffset(pos.startX, pos.startY);
        }
        contentStream.showText(pdfText.getName() == null ? "" : pdfText.getName());
        contentStream.endText();

        // 下划线
        if (pdfText.isUnderline()) {
            contentStream.setLineWidth(pdfText.getFontSize() / 10);
            contentStream.setStrokingColor(pdfText.getTextColor());
            // 实线无间隔
            contentStream.setLineDashPattern(BorderStyle.SOLID.getPattern(), BorderStyle.SOLID.getPhase());
            // 设置Y轴起始位置，背景占位为当前位置向上高度
            contentStream.moveTo(pos.startX, pos.startY - pdfText.getFontSize() / 10 / 2);
            contentStream.lineTo(pos.startX + stringWidth, pos.startY - pdfText.getFontSize() / 10 / 2);
            contentStream.stroke();
        }
    }

    public static float getStringWidth(FontClass fontClass, String name, boolean block, float fontSize) {
        try {
            if (block) {
                return fontClass.getBoldFont().getStringWidth(name) / 1000 * fontSize;
            } else {
                return fontClass.getNormalFont().getStringWidth(name) / 1000 * fontSize;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static float getStringWidth(FontClass fontClass, char name, boolean block, float fontSize) {
        try {
            if (block) {
                return fontClass.getBoldFont().getStringWidth(String.valueOf(name)) / 1000 * fontSize;
            } else {
                return fontClass.getNormalFont().getStringWidth(String.valueOf(name)) / 1000 * fontSize;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static float getStringHeight(FontClass fontClass, boolean block, float fontSize) {
        if (block) {
            return fontClass.getBoldFont().getFontDescriptor().getCapHeight() / 1000 * fontSize;
        } else {
            return fontClass.getNormalFont().getFontDescriptor().getCapHeight() / 1000 * fontSize;
        }
    }
}
